From 75d8ec00f2075b948c3303349f33fe51eb89b3c6 Mon Sep 17 00:00:00 2001 From: robertlipe Date: Wed, 17 Sep 2014 05:15:44 +0000 Subject: [PATCH] Add error checking for flagrantly malformed xcsv files. Tested: ./testo on Mac. --- gpsbabel/csv_util.cc | 49 ++++++++++++++++++++++----------------- gpsbabel/gbfile.cc | 55 +++++++++++--------------------------------- gpsbabel/gbfile.h | 3 --- 3 files changed, 41 insertions(+), 66 deletions(-) diff --git a/gpsbabel/csv_util.cc b/gpsbabel/csv_util.cc index f5a1f69f0..311d1a362 100644 --- a/gpsbabel/csv_util.cc +++ b/gpsbabel/csv_util.cc @@ -24,12 +24,14 @@ #include #include #include + #include "defs.h" #include "csv_util.h" +#include "garmin_fs.h" #include "grtcirc.h" -#include "strptime.h" #include "jeeps/gpsmath.h" -#include "garmin_fs.h" +#include "src/core/logging.h" +#include "strptime.h" #define MYNAME "CSV_UTIL" @@ -175,15 +177,6 @@ static UrlLink* link_; /* usage: p = csv_stringclean(stringtoclean, "&,\"") */ /* (strip out ampersands, commas, and quotes. */ /*********************************************************************/ -// Implement the C version via Qt - the reverse of most of our shims. -char* -csv_stringclean(const char* source, const char* chararray) -{ - /* Make a copy of the source... */ - QString cleansed(csv_stringclean(QString(source), chararray)); - return xstrdup(cleansed); -} - QString csv_stringclean(const QString& source, const QString& to_nuke) { @@ -749,6 +742,23 @@ xcsv_file_init(void) xcsv_file.gps_datum = GPS_DATUM_WGS84; } +void validate_fieldmap(field_map_t* fmp, bool is_output) { + QString qkey = fmp->key; + QString qval = fmp->val; + QString qprintfc = fmp->printfc; + + if (qkey.isEmpty()) { + Fatal() << MYNAME << ": xcsv style is missing" << + (is_output ? "output" : "input") << "field type."; + } + if (!fmp->val) { + Fatal() << MYNAME << ": xcsv style" << qkey << "is missing default."; + } + if (is_output && !fmp->printfc) { + Fatal() << MYNAME << ": xcsv style" << qkey << "output is missing format specifier."; + } +} + /*****************************************************************************/ /* xcsv_ifield_add() - add input field to ifield queue. */ /* usage: xcsv_ifield_add("DESCRIPTION", "", "%s") */ @@ -763,6 +773,7 @@ xcsv_ifield_add(char* key, char* val, char* pfc) fmp->hashed_key = xm ? xm->xt_token : -1; fmp->val = val; fmp->printfc = pfc; + validate_fieldmap(fmp, false); ENQUEUE_TAIL(&xcsv_file.ifield, &fmp->Q); xcsv_file.ifield_ct++; @@ -783,6 +794,7 @@ xcsv_ofield_add(char* key, char* val, char* pfc, int options) fmp->val = val; fmp->printfc = pfc; fmp->options = options; + validate_fieldmap(fmp, true); ENQUEUE_TAIL(xcsv_file.ofield, &fmp->Q); xcsv_file.ofield_ct++; @@ -1598,7 +1610,6 @@ xcsv_waypt_pr(const Waypoint* wpt) i = 0; QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) { - char* obuff; double lat = latitude; double lon = longitude; /* @@ -1657,7 +1668,7 @@ xcsv_waypt_pr(const Waypoint* wpt) anyname = wpt->notes; } if (anyname.isEmpty()) { - anyname = xstrdup(fmp->val); + anyname = fmp->val; } buff = QString().sprintf(fmp->printfc, CSTR(anyname)); } @@ -2113,10 +2124,10 @@ xcsv_waypt_pr(const Waypoint* wpt) warning(MYNAME ": Unknown style directive: %s\n", fmp->key); break; } - obuff = csv_stringclean(CSTR(buff), xcsv_file.badchars); + QString obuff = csv_stringclean(buff, xcsv_file.badchars); if (field_is_unknown && fmp->options & OPTIONS_OPTIONAL) { - goto next; + continue; } if (xcsv_file.field_encloser) { @@ -2128,18 +2139,14 @@ xcsv_waypt_pr(const Waypoint* wpt) * ""%s"" to smuggle bad characters through. */ if (0 == strcmp(fmp->printfc, "\"%s\"")) { - gbfprintf(xcsv_file.xcsvfp, "\"%s\"", obuff); - } else { - gbfprintf(xcsv_file.xcsvfp, "%s", obuff); + obuff = '"' + obuff + '"'; } + gbfputs(obuff, xcsv_file.xcsvfp); if (xcsv_file.field_encloser) { /* print the enclosing character(s) */ gbfprintf(xcsv_file.xcsvfp, "%s", xcsv_file.field_encloser); } - -next: - xfree(obuff); } gbfprintf(xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); diff --git a/gpsbabel/gbfile.cc b/gpsbabel/gbfile.cc index c6d5c9d44..fb1462ecb 100644 --- a/gpsbabel/gbfile.cc +++ b/gpsbabel/gbfile.cc @@ -776,12 +776,6 @@ gbfputc(int c, gbfile* file) * gbfputs: (as fputs) */ -int -gbfputs(const char* s, gbfile* file) -{ - return gbfwrite(s, 1, strlen(s), file); -} - // This is a depressing hack, meant to ease the pain from C strings // to QStrings, which are consitently encoded. int @@ -1228,24 +1222,13 @@ gbfputflt(const float f, gbfile* file) * gbfputcstr: write a NULL terminated string into a stream (!) including NULL * return the number of written characters */ - int -gbfputcstr(const char* s, gbfile* file) +gbfputcstr(const QString& s, gbfile* file) { - int len; - - len = (s == NULL) ? 0 : strlen(s); - if (len > 0) { - return gbfwrite(s, 1, len + 1, file); - } else { - gbfputc(0, file); - return 1; - } -} -int -gbfputcstr(const QString& s, gbfile* file) -{ - return gbfputcstr(qPrintable(s), file); + QByteArray qs = s.toUtf8(); + int rv = gbfwrite(qs.constData(), 1, qs.size(), file); + gbfputc(0, file); + return rv; } /* @@ -1253,29 +1236,17 @@ gbfputcstr(const QString& s, gbfile* file) * return the number of written characters */ -int -gbfputpstr(const char* s, gbfile* file) -{ - int len; - - len = (s == NULL) ? 0 : strlen(s); - if (len > 255) { - len = 255; /* the maximum size of a standard pascal string */ - } - gbfputc(len, file); - if (len > 0) { - gbfwrite(s, 1, len, file); - } - return (len + 1); -} - int gbfputpstr(const QString& s, gbfile* file) { - const char* t = xstrdup(CSTR(s)); - int r = gbfputpstr(t, file); - xfree(t); - return r; + QString out(s); + // Pascal strings can be a max of 255 bytes. + out.truncate(255); + + gbfputc(out.size(), file); + QByteArray qs = s.toUtf8(); + int rv = gbfwrite(qs.constData(), 1, qs.size(), file); + return rv; } /* Much more higher level functions */ diff --git a/gpsbabel/gbfile.h b/gpsbabel/gbfile.h index 7cf0c726a..2aa17d3bd 100644 --- a/gpsbabel/gbfile.h +++ b/gpsbabel/gbfile.h @@ -100,7 +100,6 @@ QString gbfgets(char* buf, int len, gbfile* file); int gbvfprintf(gbfile* file, const char* format, va_list ap); int gbfprintf(gbfile* file, const char* format, ...); int gbfputc(int c, gbfile* file); -int gbfputs(const char* s, gbfile* file); int gbfputs(const QString& s, gbfile* file); int gbfwrite(const void* buf, const gbsize_t size, const gbsize_t members, gbfile* file); int gbfflush(gbfile* file); @@ -132,10 +131,8 @@ int gbfputint32(const int32_t i, gbfile* file); int gbfputdbl(const double d, gbfile* file); // write a double value int gbfputflt(const float f, gbfile* file); // write a float value -int gbfputcstr(const char* s, gbfile* file); // write string including '\0' int gbfputcstr(const QString& s, gbfile* file); // write string including '\0' -int gbfputpstr(const char* s, gbfile* file); // write as pascal string int gbfputpstr(const QString& s, gbfile* file); // write as pascal string gbsize_t gbfcopyfrom(gbfile* file, gbfile* src, gbsize_t count); -- 2.30.2